%
% Carátula oficial de 75.02 Algoritmos y Programación I, cátedra Cardozo.
%
% Basado en el template realizado por Diego Essaya, disponible en
%                                                         http://lug.fi.uba.ar
% Modificado por Michel Peterson.
% Modificado por Sebastián Santisi.
% Afando por Juan Antonio Zuloaga para el tp de Orga66.20
% lalala maxi

%
% Acá se define el tamaño de letra principal:
%
\documentclass[10pt]{article}

%------------------------- Carga de paquetes ---------------------------
%
% Si no necesitás algún paquete, comentalo.
%

%
% Definición del tamaño de página y los márgenes:
%
\usepackage[a4paper,headheight=16pt,scale={0.7,0.8},hoffset=0.5cm]{geometry}

%
% Vamos a escribir en castellano:
%
\usepackage[spanish]{babel}
%\usepackage[latin1]{inputenc}
\usepackage[utf8]{inputenc}


%
% Si preferís el tipo de letra Helvetica (Arial), descomentá las siguientes
% dos lineas (las fórmulas seguirán estando en Times):
%
%\usepackage{helvet}
%\renewcommand\familydefault{\sfdefault}

%
% El paquete amsmath agrega algunas funcionalidades extra a las fórmulas. 
% Además defino la numeración de las tablas y figuras al estilo "Figura 2.3", 
% en lugar de "Figura 7". (Por lo tanto, aunque no uses fórmulas, si querés
% este tipo de numeración dejá el paquete amsmath descomentado).
%
\usepackage{amsmath}
\numberwithin{equation}{section}
\numberwithin{figure}{section}
\numberwithin{table}{section}

%
% Para tener cabecera y pie de página con un estilo personalizado:
%
\usepackage{fancyhdr}

%
% Para poner el texto "Figura X" en negrita:
% (Si no tenés el paquete 'caption2', probá con 'caption').
%
\usepackage[hang,bf]{caption2}

%
% Para poder usar subfiguras: (al estilo Figura 2.3(b) )
%
%\usepackage{subfigure}

%
% Para poder agregar notas al pie en tablas:
%
%\usepackage{threeparttable}

%------------------------------ graphicx ----------------------------------
%
% Para incluir imágenes, el siguiente código carga el paquete graphicx 
% según se esté generando un archivo dvi o un pdf (con pdflatex). 

% Para generar dvi, descomentá la linea siguiente:
%\usepackage[dvips]{graphicx}

% Para generar pdf, descomentá las dos lineas seguientes:
\usepackage[pdftex]{graphicx}
\pdfcompresslevel=9

\usepackage[final]{pdfpages}


%
% Todas las imágenes están en el directorio tp-img:
%
\newcommand{\imgdir}{includes}
\graphicspath{{\imgdir/}}
%
%------------------------------ graphicx ----------------------------------

% Necesitas este paquete si haces los diagrámas de flujo en el prográma Dia 
%\usepackage{tikz}


%------------------------- Inicio del documento ---------------------------

%
% Carátula:
%
% Título principal del documento.
\title{ \includegraphics[scale=0.3]{fiuba}
\\
\textbf{TRABAJO PRÁCTICO Nº1}
\\  Conjunto de instrucciones MIPS}

% Información sobre los autores.
\author{Juan Antonio Zuloaga Mellino, \textit{Padrón Nro. 89.537}                     \\
            \texttt{ jzuloaga@fi.uba.ar }                                              \\
            Damián Ezequiel Moguilevsky, \textit{Padrón Nro. 90.174}                     \\
            \texttt{ dmoguilevsky@fi.uba.ar }                                              \\
            Maximiliano Gismondi, \textit{Padrón Nro. 89.957}                     \\
            \texttt{ maxig88@gmail.com }                                              \\
            \normalsize{ Año 2011 - 1\textsuperscript{er} Cuatrimestre}                       \\
            \normalsize{66.20 Organización de Computadoras}                             \\
            \normalsize{Facultad de Ingeniería, Universidad de Buenos Aires}            \\
       }
%\date{\today}
\date{} %Sin Fecha


\begin{document}

%
% Hago que en la cabecera de página se muestre a la derecha la sección,
% y en el pie, en número de página a la derecha:
%
\pagestyle{fancy}
\renewcommand{\sectionmark}[1]{\markboth{}{\thesection\ \ #1}}
\lhead{}
\chead{}
\rhead{\rightmark}
\lfoot{}
\cfoot{}
\rfoot{\thepage}



\begin{titlepage}

% Inserta el título.
\maketitle
\vfill
% Resumen
\begin{abstract}
La aplicación desarrollada en el presente trabajo práctico permite hallar el mímimo comúm múltiplo y máximo común divisor entre dos números. Ésta fue íntegramente desarrollada en el lenguaje de alto nivel C a fin de aprovechar su portabilidad, pero además incluyen implementaciones especificas, escritas en lenguaje ensamblador para procesadores con arquitectura MIPS32, de los algoritmos encargados de resolver los cálculos.
\end{abstract}

\vfill
% Quita el número en la primer página.
\thispagestyle{empty}
\end{titlepage}


\newpage

%
% Hago que las páginas se comiencen a contar a partir de aquí:
%
\setcounter{page}{1}

%
% Pongo el índice en una página aparte:
\tableofcontents
\pagebreak
%
% Inicio del TP:
%
\section{Introducción}
A la hora de desarrollar aplicaciones hoy en día es común usar lenguajes de programación de alto nivel\cite{HLPL} como C++, Java o Pyhton, los cuales incluyen entre sus características la portabilidad del codigo escrito con ellos entre distintas plataformas.

Esto significa que una aplicación escrita en alguno de estos lenguajes puede ser ejecutada en computadoras con distintos sistemas operativos o cuyos procesadores posean arquitecturas diferentes sin necesidad de reescribir, al menos totalmente, el código fuente.

Por otro lado, el lenguaje ensamblador no posee esta característica, por lo tanto, si nos encontraramos en el caso anterior sería necesario reescribirla completamente.

Sin embargo utilizando este lenguaje adecuadamente se pueden escribir aplicaciones más eficientes y además, y de aquí proviene gran parte del interés academico en aprenderlo, al utilizar este lenguaje se tiene un mayor conocimiento sobre \emph{qué} hace la computadora al ejecutar la aplicación.

\section{Diseño e Implementación}
La implementación del presente trabajo está escrita, en su totalidad, en lenguaje C y, parcialmente, en lenguaje ensamblador para MIPS32 respetando la ABI\cite{ABI} descripta en clase. Es decir que puede utilizarse una versión del programa escrita únicamente en C o escrita parcialmente en C y lenguaje ensamblador, esta versión, obviamente, sólo puede ejecutarse en procesadores con arquitectura MIPS32.

Al igual que en el trabajo práctico anterior, se hace uso de la función get-opt\cite{GETOPT} de la biblioteca de GNU C para el parseo de argumentos en línea de comandos.

Como lo indica el enunciado, para calcular el máximo común divisor (de ahora en más \emph{mcd}) entre los dos números recibidos se utilizó el algoritmo de Euclides y para calcular el mínimo común múltiplo (de ahora en más \emph{mcm}) se efectúa un cálculo sencillo una vez obtenido el valor del \emph{mcd}.

Sin embargo, se debe considerar que al realizar dicho cálculo se multiplican los números de entrada, por esta razón se verifica que dichos números multiplicados no superen el valor máximo permitido, definido como:
\\\\UINT\_MAX perteneciente a la biblioteca standard \emph{limits.h}\\\\
Además se determinó que para no superar el máximo, se detecte si se produce \emph{overflow} al multiplicar los números ingresados. Para ello se comprueba lo siguiente:
\\\\\begin{center}número 1 * número 2 \emph{$<$} UINT\_MAX\end{center}

\pagebreak
\section{Escructura Funcional}
Aquí se detallará brevemente el funcionamiento de las funciones implementadas.\\
\subsection{unsigned int dcm (unsigned int m, unsigned int n)}
Calcula el \emph{mcd} a partir de los números que recibe como parámetros.
\subsection{unsigned int mcm (unsigned int m, unsigned int n)}
Calcula el \emph{mcm} a partir de los números que recibe como parámetros. Comprueba que no se produzca \emph{overflow} al multiplicar los parámetros ingresados en la función.
\subsection{int numbers(unsigned int $*$num\_1, unsigned int $*$num\_2)}
Parsea los strings almacenados en globalArgs.inputNumbers[0] y globalArgs.inputNumbers[1] y los almacena los valores numéricos en num\_1 y num\_2 respectivamente, luego valida que estos números se encuentren en el rango válido indicado en el enunciado del trabajo práctico.

Si los numeros almacenados en globalArgs.inputNumbers son validos la función retorna SUCCESS, en otro caso EXIT\_FAILURE.
\subsection{int open\_output\_file(FILE $**$ file\_o)}
Abre el archivo de salida según lo especificado por el parámetro -o. 

Si no se especificó un archivo de salida, o si se especificó explícitamente usar la salida estándar, $*$file\_o apuntará a stdout a fin de imprimir el resultado de la ejecución del programa por esta  salida y la función retornará SUCCESS.

Si se especificó un archivo de salida y el mismo no se pudo abrir en modo escritura, la función retornará EXIT\_FAILURE. En caso de que el archivo se halla podido abrir $*$file\_o apuntará al mismo y se retornará SUCCESS.
\subsection{mostrar\_version(FILE$*$ file\_o)}
Imprime la versión del ejecutable actual a través del FILE$*$ que recibe como parámetro.
\subsection{mostrar\_ayuda(FILE$*$ file\_o) }
Imprime, a través del FILE$*$ que recibe como parámetro, correspondiente la ayuda, es decir, cómo se debe invocar al programa, qué opciones hay disponibles y para qué sirve cada una.
\subsection{void inicializar\_arg()}
Inicializa los miembros de la estructura \emph{globalArgs}
\subsection{parsear\_opciones(int argc, char$*$ argv[], FILE $**$file\_o)}
Esta función es la que se encarga de examinar y determinar que opciones ingresó el usuario. De esta 
forma, mediante la utilización de la biblioteca \emph{getopt.h}, se accedió a utilizar la función \emph{getopt\_long}.
Por este motivo, resultó sencillo mediante llamadas sucesivas a la misma función y la identificación opción por opción,
determinar cuáles fueron las ingresadas por el usuario tanto en formato simple como extendido.

Por otra parte, la función de biblioteca ya cuenta intrínsicamente con la detección de aquellos casos
donde alguna de las opciones requiere un argumento y el mismo no haya sido ingresado.

Así también, resulta importante mencionar, que en base a las opciones detectadas se setean diversos \emph{flags}, así como 
de la misma forma se adquieren las rutas de los dos archivos a comparar.

\subsection{main()}
Función principal, es la primera que se invoca al ejecutar el programa. Esta funcion utiliza a las anteriormente descriptas para calcular \emph{mcm} o \emph{mcd} y mostrar el resultado según las opciones ingresadas por el usuario. Devuelve SUCCESS si no se produce ningun error.
 
\pagebreak
\section{Comandos para compilar el programa}
La implementación íntegramente escrita en C del programa se compila, utilizando gcc, con el siguiente comando:
\\
\\
\noindent \texttt{
\$ gcc -O0 funciones.c main.c -o ejecutable/common
\\
\\
}
La implementación que parte del código escrito en assembler se compila con el siguiente comando:
\\
\\
\noindent \texttt{
\$ gcc -O0 funciones.s main.c -o ejecutable/common
\\
\\
}
El ejecutable generado se alojar\'a en un directorio preexistente llamado llamado 'ejecutable' bajo el nombre 'common'.
\vfill
%\pagebreak
\section{Corridas de prueba}
Todas la corrdias de prueba fueron realizadas en la máquina virtual \emph{3max} de \emph{gxemul}, ejecutando el sistema operativo \emph{NetBSD/pmax}. A continuación se muestran las pruebas requeridas por el enunciado del trabajo práctico.
\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.5\textwidth]{./includes/prueba1.png}
\end{center}
\caption{Prueba 1. Operandos 5 y 10}
\end{figure}

\vfill

\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.5\textwidth]{./includes/prueba2.png}
\end{center}
\caption{Prueba 2. Operandos 256 y 192}
\label{fig:2y2b}
\end{figure}

\vfill

\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.76\textwidth]{./includes/stack.png}
\end{center}
\caption{Diagrama de Stack de Prueba 2}
\label{fig:2y2b}
\end{figure}

\vfill

\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.5\textwidth]{./includes/prueba3.png}
\end{center}
\caption{Prueba 3. Operandos 1111 y 1294}
\label{fig:2y2b}
\end{figure}

\vfill

\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.5\textwidth]{./includes/pruebaError.png}
\end{center}
\caption{Números fuera de rango}
\label{fig:2y2b}
\end{figure}

\vfill

\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.5\textwidth]{./includes/ayuda.png}
\end{center}
\caption{Ayuda}
\label{fig:2y2b}
\end{figure}

\vfill

\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.5\textwidth]{./includes/version.png}
\end{center}
\caption{Versión}
\label{fig:2y2b}
\end{figure}

\vfill

\pagebreak

\section{Conclusión}
El presente trabajo permitió interiorizarse con la utilización del lenguaje Assembly de la arquitectura MIPS32. Asimismo, al haber realizado la mayoría del mismo en un lenguaje de alto nivel como C, se pudo comprobar las diferencias entre el código assembly generado por el compilador automáticamente y al hacerlo manualmente. De esta manera, se pudo determinar ciertas mejoras que aplica el compilador para generar un código de bajo nivel más eficiente. Por otra parte, se pudo observar que la ABI utilizada por la cátedra difiere de la implementada por GCC en sus más recientes versiones.\\
Los principales inconvenientes surgidos durante el desarrollo del proyecto consistieron en el cumplimiento de la ABI. Puesto que si bien las funciones funcionaban correctamente, se debieron ajustar algunos parámetros para respetar aquellas variables que deben ser resguardadas tanto por la \emph{caller} como por la \emph{callee}.

%\section{Bibliografía}
\begin{thebibliography}{99}
\bibitem{HLPL} High-level programming language,\\
http://en.wikipedia.org/wiki/High-level\_programming\_language
\bibitem{ABI} Application binary interface,\\
http://en.wikipedia.org/wiki/Application\_binary\_interface
\bibitem{GETOPT} linux.die.net ``Linux man pages,'' 2011,\\
http://linux.die.net/man/3/getopt\_long
\bibitem{HP} ``Computer Organization and Design: The Hardware/Software Interface.'',\\
3d edition - Appendix A, Hennessy \& Patterson.
\bibitem{SystemV} System VApplication Binary Interace, 1996,\\
MIMPS RISC Processor Supplement 3rd edition
\bibitem{MAH} Mips Abi History,\\
http://www.linux-mips.org/wiki/MIPSABIHistory
\end{thebibliography}



\appendix{}
\section{Notas respecto a la ABI y el compilador \emph{GCC}}
A lo largo del trabajo nos fue imoposible encontrar un criterio común para la ABI, ya que entraban en conflicto distintas cosas.
Principalmente las diferencias se encontraron entre los valores que se le cargan en \$fp en \emph{gcc -mabi=n32} en que se lo iguala al \$sp contra Patterson-Hennessy que recomienda cargarle la primera dirección en el main.
También se encontraron diferencias entre la Abi de System V, en donde no es necesario slavar el \$gp ni el \$sp si estos no son modificados, contra las recomendaciones de la cátedra.
Por último, la escritura en el global pointer sin ser recalculado previamente produce warnings de linkeo en gcc que compila bajo la abi de SGI.
\includepdf[pages={1,2,3,4}]{tp1-q1-2011}
\end{document}
